namespace NHCodeFirst.Helpers
{
    using System.Web;
    using NHibernate;
    using NHibernate.Cfg;

    public class NHibernateHelper
    {
        private static ISessionFactory sessionFactory;
        private static ISession session;

        public static void BuildSessionFactory(Configuration configuration)
        {
            if (sessionFactory != null)
                return;
            lock (NHibernateConfiguration.Mappings)
            {
                var cfg = configuration ?? new Configuration().Configure();
                foreach (var mapping in NHibernateConfiguration.Mappings)
                    cfg.AddXmlString(mapping);
                sessionFactory = cfg.BuildSessionFactory();
            }
        }

        public static ISession GetCurrentSession()
        {
            var webSession = GetWebSession();
            return webSession ?? GetWinAppSession();
        }

        public static void CloseSession()
        {
            var webSession = GetWebSession();
            if (webSession != null)
            {
                webSession.Close();
                HttpContext.Current.Items.Remove("NHSession");
            }
            else
            {
                var winAppSession = GetWinAppSession();
                winAppSession.Close();
                session = null;
            }
        }

        public static void CloseSessionFactory()
        {
            if (sessionFactory != null)
                sessionFactory.Close();
        }

        private static ISession GetWebSession()
        {
            var context = HttpContext.Current;
            if (context == null)
                return null;
            var currentSession = context.Items["NHSession"] as ISession;

            if (currentSession == null)
            {
                currentSession = sessionFactory.OpenSession();
                context.Items["NHSession"] = currentSession;
            }

            return currentSession;
        }

        private static ISession GetWinAppSession()
        {
            return session ?? (session = sessionFactory.OpenSession());
        }
    }
}